package wisp.game;

import java.awt.image.BufferedImage;

import wisp.dataObjects.God;
import wisp.dataObjects.Monster;
import wisp.dataObjects.MonsterType;
import wisp.dataObjects.Statistics;
import wisp.dataObjects.WispCharacter;

import com.golden.gamedev.Game;
import com.golden.gamedev.object.Timer;

public class SummonedMonsterSprite extends CharacterSprite{


		private Timer monsterTimer;
	    private String type;
	    private Game maingame;
	    
	    //
	    private boolean hasTarget;
	    private boolean attackMode;
	    private CharacterSprite target;
	    
	    //
	    private double range;
	    private God monsterData;
	    private Monster monsterData2;
	    private double totalDamage;
	    
	    /** Creates a new instance of MonsterSprite */
	    public SummonedMonsterSprite(String name, MainGame game, BufferedImage[] images, double x, double y, Game g) {
	        super(name, "MONSTER", game,images,x,y,false);
	       
	        initObject();
	        initStats(monsterData.getMaxHP(),monsterData.getMaxHP(),0,0,500);
	       // initStats(120,120,60,60,500);
	        range = 150;
	        //
	        this.setName(name);
	        setSelectable(true);
	        
	        int atktimer = ((Double)this.getStatistics().getARate()).intValue() * 10;
	        System.out.println ("bleh: " + atktimer);
	        monsterTimer = new Timer(atktimer);
	        monsterTimer.setActive(true);
	        type = "MONSTER";
	        
	        //
	        maingame = g;
	    }
	    
	    
	/*    public void setActive(boolean b) {
	        super.setActive(b);
	        monsterTimer.setActive(b);
	    }*/
	    public int[] getUpImages() {
	        return new int[] {0};
	    }
	    public int[] getDownImages(){
	        return new int[] {0};
	    }
	    public int[] getLeftImages(){
	        return new int[] {0};
	    }
	    public int[] getRightImages(){
	        return new int[] {0};
	    }  
	    
	    //ADDED//
	    public int[] getUpFlinch(){
	    	return new int[]{1};
	    }
	    
	    public int[] getDownFlinch(){
	    	return new int[]{1};    
	    }
	    
	    public int[] getLeftFlinch(){
	    	return new int[]{1};
	    }
	    
	    public int[] getRightFlinch(){
	    	return new int[]{1};
	    }
	    //END ADDED//
	    
	    ///////////added - for buff <DUMMY since not needed>
	    public int[] getUpBuffed(){
	    	return new int[]{2};
	    }
	    public int[] getDownBuffed(){
	    	return new int[]{2};
	    }
	    public int[] getLeftBuffed(){
	    	return new int[]{2};
	    }
	    public int[] getRightBuffed(){
	    	return new int[]{2};
	    }
	    ///////////////////
	    
	    protected void randomMove() {
	        int dispx = getGame().getRandom(-50,50);
	        int dispy = getGame().getRandom(-50,50);
	        setMoveLocation(getMiddleX()+dispx, getMiddleY()+dispy);
	    }
	    public void update(long elapsedTime) {
	    	if(hasTarget){
	        	//following checks what action player wants to perform
	        	if(attackMode){
	        			if ( isDead() == false && target.isDead() == false)
	        			{	//System.out.println ("lalalalala");
	        				if(inRange(target, this))
	        				{	
	        					commenceAttack(elapsedTime);
	        					if(target!=null)
	        	        			setMoveLocation(target.getScreenX(), target.getScreenY());
	        				}
	        				else
	        				{	//System.out.println("[" + this.getName() + "] : User has gone out of attack range\n");
	        					//this.hasTarget = false;
	        					//resetMode();
	        					setMoveLocation(target.getX(), target.getY());
	        					
	        				}	
	        				move(elapsedTime);
	        			}
	        		
	        			else
	        			{
	        				resetMode();
	        				this.hasTarget = false;
	        			}
	        	}
	        }
	    	/*else if(monsterTimer.action(elapsedTime) && attackMode == false) {
	            randomMove();
	        }
	        else 
	        	move(elapsedTime);*/
	    	
	        super.update(elapsedTime);
	    }
	    
	    public boolean inRange(CharacterSprite cs, CharacterSprite self){
	    	boolean value;
	    	double xdistance = 0;
	    	double ydistance = 0;
	    	
	    	if(cs.getScreenX() > self.getScreenX()){
	    		xdistance = cs.getScreenX() - self.getScreenX();
	    	}
	    	else
	    		xdistance = self.getScreenX() - cs.getScreenX();
	    	
	    	if(cs.getScreenY() > self.getScreenY()){
	    		ydistance = cs.getScreenY() - self.getScreenY();
	    	}
	    	else
	    		ydistance = self.getScreenY() - cs.getScreenY();
	    	
	    	//System.out.println(">>>> RANGE DIST : X>" + xdistance + " Y>" + ydistance + "\n\n");
	    	
	    	if(xdistance > this.range || ydistance > this.range){
	    		value = false;
	    	}
	    	else
	    		value = true;
	    	
	    	return value;
	    }
	    
		public void commenceAttack(long elapsedTime) 
		{

			//checkForSkillUsed() skills must interrupt normal attack if used so its first
			if ( monsterTimer.action(elapsedTime)) //okay to attack
			{
				//System.out.println ("hihihihihih");
				performNormalAttack();
			}
		}

		public void performNormalAttack() {
			
			double damage = 0;
			
			boolean attackFlag = attackIsSuccessful ();
			if(target!=null){
			
				System.out.println("[COMBAT] " + this.getName() + " attacks " + target.getName());
				
				if ( attackFlag == true)
				{

					damage = this.computeDamage(attackFlag);
					//System.out.println ("bahahahahaah");
					target.hit(this, damage);	
					
					if(target!=null)
						System.out.println("[COMBAT] " + target.getName() + " takes " + damage + " dmg");
				}
		    	else
		    	{	System.out.println("[COMBAT] " + this.getName() + " misses");
		    		target.hit(this,0);
		    	}
				
				
			}
		}
			

		private double computeDamage(boolean value) {
			WispCharacter wispcharacter = (WispCharacter)target.getData();
			return getActions().computeDamageM(monsterData2, this.getStatistics(), target.getStatistics(), wispcharacter, value);
		}

		private boolean attackIsSuccessful() {
			//System.out.println ("lalalalala");
			if (getActions().getSuccessACC(getStatistics().getARate()) == true)
				return true;
			else
				return false;
		}
	    
	    public void selected() {
	    	//System.out.println("A Monster was selected.");
	    	getGame().bsInput.refresh();
	    }
	    
	    public void clicked() {
		
	    	//if (isSelected())
	    	//System.out.println("clicked.");	
	}

	    public void deselected() {
	    	//System.out.println("A Monster was deselected.");
	    }
	    
	    public void resetMode()
	    {
	    	attackMode = false;
	    	hasTarget = false;
	        target = null;
	        setDamagedRecieved(-1);
	        this.setFlinch(false);
	        totalDamage = 0;
	    }
	    
	    public Object getData()
	    {
	    	return getMonsterData2();
	    }
	    
	    public void setMonsterData2(Monster monsterData2) {
	    	this.monsterData2 = monsterData2;
	    }
	    
	    public Monster getMonsterData2() {
	    	return monsterData2;
	    }
	    
	    @Override
	    public void initObject() {
	   // 	monsterData = new MonsterType ("Squiggly", "Sallela", "description", 80, 40, 1);
	    	monsterData = new God();
	    	monsterData.viewCurseInfo(this.getName());
	    	monsterData2 = new Monster(monsterData.getMaxHP(), 0, 0, 500, 500, 0, this.getName());
	    	
	    	if (this.getName().equals("Cockatrice"))
	    		setStatistics(new Statistics("Cockatrice", 1, 1, 1, 1, 1, 6, 9, 1, 1, 1.5, 1, 1, 1, 1, 60, .6, 1));
	    	
	    	else if (this.getName().equals("Goblin"))
	    		setStatistics(new Statistics ("Goblin", 1, 1, 1, 4, 1, 5, 5, 0, 0, 1.5, 1, 1, 1, 1, 70, .7, 1));
	    	
	    	else if (this.getName().equals("Troll"))
	    		setStatistics(new Statistics ("Troll", 1, 1, 1, 4, 1, 8, 3, 0, 0, 1.5, 1, 1, 1, 1, 60, .5, 1));
	 
	    	this.getStatistics().setStatType(0);
	    }
	    
	    public void hit(CharacterSprite cs, double damage)
	    {
	    	//this means the monster must realize its being attacked 
	    	//System.out.println ("pumasok sa hit ni monster!");
	    	if (attackMode == false)
	    	{	
	    		attackMode = true;
	    		target = cs;
	    		hasTarget = true;
	    		//System.out.println ("dapat naset ung hasTarget and attackMode!!!");
	    	}
	    	
	    	totalDamage = totalDamage + damage;
			///FOR DAMAGE DISPLAY
			this.setBeingDamaged(true);
			this.setDamagedRecieved(((Double)damage).intValue());
			
			this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/hit.png", 3, 1), getX()+(getWidth()/2), getY()+(getHeight()/2)));
			///FLINCH
			this.setFlinch(true);
			//

	    	this.setCurrentHP(this.getCurrentHP() - (new Double(damage).intValue()));
	    	//	
	    	this.getHp_bar().setCurrValue(new Double((new Double(this.getCurrentHP()).doubleValue() / new Double(this.getMaxHP()).doubleValue()) * 100).intValue());
	    	//
	    	//System.out.println ("Monster current HP is: " + this.getCurrentHP());
	    	// check if dead:
	    	//    true : call cs.gainEXP() --> gainEXP is in charge of checking if player has leveled
	    	if (isDead() == true)
	    	{
	    		this.getGame().getCorpseGroup().add(new Corpse(this.getName(),getGame(), (this.getGame().getImages("IMAGES/Sprites/corpse.png", 1, 1)), getX(), getY()));
	    		
	    		this.setActive(false); ///vanish monster!! pero dapat may animate death x.x
	    		target.resetMode();
	    		System.out.println("Monster is dead!");
	    		PlayerSprite player = (PlayerSprite)target;
	    		player.checkIfLevelUp(this.getExpValue());
	    		super.getGame().endCurseMode();
	    		
	    	}
	    	
	    	//call animateHit ()
	    	// call animateDamage()
	    }
	    
	    public int getExpValue()
	    {
	    	return (int) Math.ceil(totalDamage * 0.4);
	    }
		public God getMonsterData() {
			return monsterData;
		}
		public void setMonsterData(God monsterData) {
			this.monsterData = monsterData;
		}
		
		public void attack(CharacterSprite target)
		{
			this.target = target;
			this.attackMode = true;
			this.hasTarget = true;
			System.out.println("[COMBAT] " + target.getName() + " aggros " + this.getName());
		}
	}



